﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using OSGeo.MapGuide;

namespace IGIS.Core
{
    public class FeatureProperty : ICloneable
    {
        // Fields
        internal bool _initialized;
        private object _value;
        private static readonly string[] LastUpdateAliases = new string[] { "תאריך עדכון", "עדכון אחרון" };

        // Methods
        public FeatureProperty()
        {
        }

        public FeatureProperty(string name, string alias)
        {
            this.Name = name;
            this.Alias = alias;
            if (LastUpdateAliases.Contains<string>(this.Alias))
            {
                this.IsUpdated = true;
            }
        }

        public object Clone()
        {
            return new FeatureProperty { _initialized = false, Alias = this.Alias, AviableValues = this.AviableValues, IsDisplayed = this.IsDisplayed, IsIdentity = this.IsIdentity, IsReadOnly = this.IsReadOnly, IsUpdated = this.IsUpdated, LookUpValues = this.LookUpValues, Name = this.Name, PropertyType = this.PropertyType };
        }

        public MgProperty GenerateProperty()
        {
            return this.GenerateProperty(true);
        }

        public MgProperty GenerateProperty(bool changedOnly)
        {
            MgProperty prop = null;
            if ((this.IsReadOnly || this.IsIdentity) || (!this.IsUpdated && changedOnly))
            {
                return null;
            }
            switch (this.PropertyType)
            {
                case 1:
                    bool val;
                    if (!bool.TryParse(this.Value.ToString(), out val))
                    {
                        throw new InvalidOperationException(string.Format("<b>{0}</b> - נתון אינו תקין", this.Alias));
                    }
                    return new MgBooleanProperty(this.Name, val);

                case 2:
                    byte val2;
                    if (!byte.TryParse(this.Value.ToString(), out val2))
                    {
                        throw new InvalidOperationException(string.Format("<b>{0}</b> - נתון אינו תקין", this.Alias));
                    }
                    return new MgByteProperty(this.Name, val2);

                case 3:
                    {
                        short day;
                        short month;
                        short year;
                        MgDateTime dt = new MgDateTime();
                        if (LastUpdateAliases.Contains<string>(this.Alias))
                        {
                            this.Value = DateTime.Now.ToString("dd/MM/yyyy");
                        }
                        string[] arrDT = this.Value.ToString().Split(new char[] { '/' });
                        if (!((short.TryParse(arrDT[0], out day) && short.TryParse(arrDT[1], out month)) && short.TryParse(arrDT[2], out year)))
                        {
                            throw new InvalidOperationException(string.Format("<b>{0}</b> פורמת תאריך שגוי", this.Alias));
                        }
                        dt.Day = day;
                        dt.Month = month;
                        dt.Year = year;
                        return new MgDateTimeProperty(this.Name, dt);
                    }
                case 4:
                    return prop;

                case 5:
                    double val3;
                    if (!double.TryParse(this.Value.ToString(), out val3))
                    {
                        throw new InvalidOperationException(string.Format("<b>{0}</b> חייב להיות מספר", this.Alias));
                    }
                    return new MgDoubleProperty(this.Name, val3);

                case 6:
                    short val4;
                    if (!short.TryParse(this.Value.ToString(), out val4))
                    {
                        throw new InvalidOperationException(string.Format("<b>{0}</b> חייב להיות מספר", this.Alias));
                    }
                    return new MgInt16Property(this.Name, val4);

                case 7:
                    int val5;
                    if (!int.TryParse(this.Value.ToString(), out val5))
                    {
                        throw new InvalidOperationException(string.Format("<b>{0}</b> חייב להיות מספר", this.Alias));
                    }
                    return new MgInt32Property(this.Name, val5);

                case 8:
                    long val6;
                    if (!long.TryParse(this.Value.ToString(), out val6))
                    {
                        throw new InvalidOperationException(string.Format("<b>{0}</b> חייב להיות מספר", this.Alias));
                    }
                    return new MgInt64Property(this.Name, val6);

                case 9:
                    return new MgStringProperty(this.Name, this.Value.ToString());
            }
            return prop;
        }

        // Properties
        public string Alias { get; set; }

        public List<string> AviableValues { get; set; }

        public string DisplayedValue
        {
            get
            {
                if (this._value == null)
                {
                    return string.Empty;
                }
                if ((this.LookUpValues != null) && this.LookUpValues.ContainsKey(Convert.ToInt32(this.Value)))
                {
                    return this.LookUpValues[Convert.ToInt32(this.Value)];
                }
                if (this._value.GetType() == typeof(DateTime))
                {
                    DateTime dt = (DateTime)this.Value;
                    return ((dt.Year == 1) ? string.Empty : dt.ToString("dd/MM/yyyy"));
                }
                return this.Value.ToString();
            }
        }

        public bool IsDisplayed { get; set; }

        public bool IsIdentity { get; set; }

        public bool IsLookupWithCode { get; set; }

        public bool IsReadOnly { get; set; }

        public bool IsUpdated { get; set; }

        public Dictionary<int, string> LookUpValues { get; set; }

        public string Name { get; set; }

        public int OrderId { get; set; }

        public int PropertyType { get; set; }

        public object Value
        {
            get
            {
                return this._value;
            }
            set
            {
                if ((this._value == null) || !(this._value.ToString() == value.ToString()))
                {
                    if (!((this.AviableValues == null) || this.AviableValues.Contains(value.ToString())))
                    {
                        throw new InvalidOperationException(string.Format("נתונים שגוים בשדה <b>{0}</b>", this.Alias));
                    }
                    this._value = value;
                    if (this._initialized)
                    {
                        this.IsUpdated = true;
                    }
                }
            }
        }
    }


}